package com.macro.mall.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.rholder.retry.*;
import com.macro.mall.common.config.XhsApiConfig;
import com.macro.mall.common.exception.XhsApiException;
import com.macro.mall.dto.PmsProductQueryParam;
import com.macro.mall.model.request.ProductBatchGetRequest;
import com.macro.mall.model.request.ProductGetRequest;
import com.macro.mall.model.request.SkuBatchOfflineRequest;
import com.macro.mall.model.request.SkuBatchOnlineRequest;
import com.macro.mall.model.response.ProductBatchGetResponse;
import com.macro.mall.model.response.ProductGetResponse;
import com.macro.mall.model.response.SkuBatchOnlineResponse;
import com.macro.mall.service.XhsLoginService;
import com.macro.mall.service.XhsProductService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class XhsProductServiceImpl implements XhsProductService {


    @Value("${xhs.app-id}")
    private String appId;

    @Resource
    private OkHttpClient httpClient;

    @Resource
    private  ObjectMapper objectMapper;

    @Resource
    private XhsApiConfig apiConfig;

    @Resource
    private XhsLoginService xhsLoginService;



    @Override
    public ProductBatchGetResponse batchGetProducts(PmsProductQueryParam productQueryParam, Integer pageSize, Integer pageNum) {
        String apiUrl = "https://miniapp-sandbox.xiaohongshu.com" + "/api/rmp/mp/deal/product/batch_get";
        ProductBatchGetRequest request = new ProductBatchGetRequest();
        request.setPageNo(pageNum);
        request.setPageSize(pageSize);
        if (ObjectUtil.isNotNull(productQueryParam.getPublishStatus())){
            request.setStatus(productQueryParam.getPublishStatus());
        }
        try {
            String validToken = null;
            try {
                validToken = xhsLoginService.getValidToken();
            } catch (XhsApiException e) {
                throw new RuntimeException(e);
            }
            // 1. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", validToken)
                    .build();

            // 2. 构建请求体
            String jsonBody = objectMapper.writeValueAsString(request);
            RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

            // 3. 构建请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 4. 执行请求
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("商品批量获取失败，HTTP状态码: {}", response.code());
                    throw new RuntimeException("API请求失败，状态码: " + response.code());
                }

                // 5. 解析响应
                String responseBody = response.body().string();
                return objectMapper.readValue(responseBody, ProductBatchGetResponse.class);
            }
        } catch (IOException e) {
            log.error("商品批量获取异常", e);
            throw new RuntimeException("商品批量获取异常", e);
        }
    }

    @Override
    public void updateSXHGoods(List<Long> ids, Integer status) {

    }

    // 在类中定义Retryer实例
    private final Retryer<ProductGetResponse> productRetryer = RetryerBuilder.<ProductGetResponse>newBuilder()
            .retryIfException() // 对所有异常重试
            .retryIfRuntimeException() // 对RuntimeException重试
            .withWaitStrategy(WaitStrategies.exponentialWait(1000, 5, TimeUnit.SECONDS)) // 指数退避
            .withStopStrategy(StopStrategies.stopAfterAttempt(10)) // 最多重试3次
            .withRetryListener(new RetryListener() {
                @Override
                public <V> void onRetry(Attempt<V> attempt) {
                    if (attempt.hasException()) {
                        log.warn("商品获取失败，准备第{}次重试... 异常: {}",
                                attempt.getAttemptNumber(),
                                attempt.getExceptionCause().getMessage());
                    }
                }
            })
            .build();

    @SneakyThrows
    @Override
    public ProductGetResponse getProduct(ProductGetRequest request) {
        String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/mp/deal/product/get";

        return productRetryer.call(() -> {
            String validToken = null;
            try {
                validToken = xhsLoginService.getValidToken();
            } catch (XhsApiException e) {
                throw new RuntimeException("获取Token失败", e);
            }

            try {
                // 1. 构建请求URL
                HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                        .addQueryParameter("app_id", apiConfig.getAppId())
                        .addQueryParameter("access_token", validToken)
                        .build();

                // 2. 构建请求体
                String jsonBody = objectMapper.writeValueAsString(request);
                RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

                // 3. 构建请求
                Request httpRequest = new Request.Builder()
                        .url(url)
                        .post(body)
                        .addHeader("Content-Type", "application/json")
                        .build();

                // 4. 执行请求
                try (Response response = httpClient.newCall(httpRequest).execute()) {
                    if (!response.isSuccessful()) {
                        log.error("商品获取失败，HTTP状态码: {}", response.code());
                        throw new RuntimeException("API请求失败，状态码: " + response.code());
                    }

                    // 5. 解析响应
                    String responseBody = response.body().string();
                    return objectMapper.readValue(responseBody, ProductGetResponse.class);
                }
            } catch (IOException e) {
                log.error("商品获取异常", e);
                throw new RuntimeException("商品获取异常", e);
            }
        });
    }


    @Override
    public SkuBatchOnlineResponse batchOnlineSkus(SkuBatchOnlineRequest request) {
        // 验证SKU数量不超过100个
        if (request.getOutSkuIds().size() > 100) {
            throw new IllegalArgumentException("单次上架SKU数量不能超过100个");
        }

        String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/mp/deal/product/sku/batch_online";

        String validToken;
        try {
            validToken = xhsLoginService.getValidToken();
        } catch (XhsApiException e) {
            throw new RuntimeException("获取access_token失败", e);
        }

        try {
            // 1. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", validToken)
                    .build();

            // 2. 构建请求体
            String jsonBody = objectMapper.writeValueAsString(request);
            RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

            // 3. 构建请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 4. 执行请求
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("SKU批量上架失败，HTTP状态码: {}", response.code());
                    throw new RuntimeException("API请求失败，状态码: " + response.code());
                }

                // 5. 解析响应
                String responseBody = response.body().string();
                return objectMapper.readValue(responseBody, SkuBatchOnlineResponse.class);
            }
        } catch (IOException e) {
            log.error("SKU批量上架异常", e);
            throw new RuntimeException("SKU批量上架异常", e);
        }

    }

    @Override
    public SkuBatchOnlineResponse batchOfflineSkus(SkuBatchOfflineRequest request) {
        // 验证SKU数量不超过100个
        if (request.getOutSkuIds().size() > 100) {
            throw new IllegalArgumentException("单次下架SKU数量不能超过100个");
        }

        String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/mp/deal/product/sku/batch_offline";

        String validToken;
        try {
            validToken = xhsLoginService.getValidToken();
        } catch (XhsApiException e) {
            throw new RuntimeException("获取access_token失败", e);
        }

        try {
            // 1. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", validToken)
                    .build();

            // 2. 构建请求体
            String jsonBody = objectMapper.writeValueAsString(request);
            RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

            // 3. 构建请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 4. 执行请求
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("SKU批量下架失败，HTTP状态码: {}", response.code());
                    throw new RuntimeException("API请求失败，状态码: " + response.code());
                }

                // 5. 解析响应
                String responseBody = response.body().string();
                return objectMapper.readValue(responseBody, SkuBatchOnlineResponse.class);
            }
        } catch (IOException e) {
            log.error("SKU批量下架异常", e);
            throw new RuntimeException("SKU批量下架异常", e);
        }

    }
}
